import os
import threading
import tkinter as tk
from tkinter import ttk, messagebox, filedialog

from utils import printer_util
from utils.log_util import get_logger
from utils.print_job_distributor_util import PrintJobDistributor
from .add_printer_dialog_view import AddPrinterDialog
from .configure_printer_dialog_view import ConfigurePrinterDialog


class PrinterView(ttk.Frame):
    def __init__(self, parent, controller, config_manager):
        super().__init__(parent)
        self.tree = None
        self.file_display_text = None
        self.controller = controller
        self.config_manager = config_manager
        self.files_to_print = []  # 存储文件信息字典的列表
        self.next_file_id = 0  # 用于生成唯一文件ID
        self.next_printer_index = 0
        self.logger = get_logger()

        # 创建打印任务分发器
        self.distributor = PrintJobDistributor(config_manager, self.logger)

        self.setup_ui()
        self.load_managed_printers()

    def setup_ui(self):
        # 主布局
        top_frame = ttk.Frame(self)
        top_frame.pack(fill=tk.X, padx=10, pady=10)

        bottom_frame = ttk.Frame(self)
        bottom_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 顶部操作按钮
        ttk.Button(
            top_frame, text="🖨 添加打印机", command=self.open_add_printer_dialog
        ).pack(side=tk.LEFT, padx=5)
        ttk.Button(
            top_frame, text="⚙️ 配置参数", command=self.open_configure_dialog
        ).pack(side=tk.LEFT, padx=5)
        ttk.Button(
            top_frame, text="🗑 移除打印机", command=self.remove_selected_printer
        ).pack(side=tk.LEFT, padx=5)
        ttk.Button(
            top_frame, text="🔄 刷新状态", command=self.refresh_printer_status
        ).pack(side=tk.LEFT, padx=5)

        # 打印机列表
        list_frame = ttk.LabelFrame(bottom_frame, text="已管理的打印机")
        list_frame.pack(fill=tk.BOTH, expand=True, side=tk.LEFT, padx=(0, 10))

        # 移除"params"列
        cols = ("name", "ip", "status")
        self.tree = ttk.Treeview(list_frame, columns=cols, show="headings")

        self.tree.heading("name", text="打印机名称")
        self.tree.heading("ip", text="IP地址")
        self.tree.heading("status", text="实时状态")

        # 调整列宽
        self.tree.column("name", width=250)
        self.tree.column("ip", width=120)
        self.tree.column("status", width=120)

        self.tree.pack(fill=tk.BOTH, expand=True, pady=5, padx=5)

        # 打印任务分配区域 - 增加宽度
        task_frame = ttk.LabelFrame(bottom_frame, text="打印任务分配")
        task_frame.pack(
            fill=tk.BOTH, expand=True, side=tk.RIGHT, padx=(10, 0), ipadx=10, ipady=5
        )

        file_btn_frame = ttk.Frame(task_frame)
        file_btn_frame.pack(pady=10, fill=tk.X)
        ttk.Button(file_btn_frame, text="📂 选择文件", command=self.select_files).pack(
            side=tk.LEFT, expand=True, fill=tk.X, padx=(0, 5)
        )
        ttk.Button(file_btn_frame, text="❌ 清空列表", command=self.clear_files).pack(
            side=tk.LEFT, expand=True, fill=tk.X
        )

        text_frame = tk.Frame(task_frame)
        text_frame.pack(pady=5, fill=tk.BOTH, expand=True)

        self.file_display_text = tk.Text(
            text_frame,
            wrap=tk.WORD,
            height=10,
            font=("Arial", 9),
            relief=tk.SUNKEN,
            borderwidth=1,
        )
        self.file_display_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 添加滚动条
        scrollbar = ttk.Scrollbar(
            text_frame, orient=tk.VERTICAL, command=self.file_display_text.yview
        )
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.file_display_text.config(yscrollcommand=scrollbar.set, state=tk.DISABLED)

        ttk.Button(
            task_frame, text="▶️ 开始打印", command=self.distribute_print_jobs
        ).pack(pady=10, fill=tk.X)

    def load_managed_printers(self):
        for i in self.tree.get_children():
            self.tree.delete(i)

        printers = self.config_manager.get_printers()
        for name, config in printers.items():
            # 移除了params_str的生成
            self.tree.insert(
                "", "end", values=(name, config.get("ip"), "正在获取..."), iid=name
            )

        self.refresh_printer_status()
        self.logger.info("已加载受管打印机列表。")

    def refresh_printer_status(self):
        printers = self.config_manager.get_printers()
        if not printers:
            return

        def update_statuses():
            for name in printers.keys():
                status = printer_util.get_printer_status(name)
                self.config_manager.update_printer_status(name, status)
                # 在主线程中更新UI
                self.after(0, self.tree.set, name, "status", status)
            self.logger.info("所有打印机状态已刷新。")

        # 使用线程避免UI阻塞
        threading.Thread(target=update_statuses, daemon=True).start()

    def open_add_printer_dialog(self):
        AddPrinterDialog(self, self.config_manager, self.load_managed_printers)

    def remove_selected_printer(self):
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showwarning("未选择", "请选择要移除的打印机。")
            return

        name = selected_item[0]
        if messagebox.askyesno("确认", f"确定要移除打印机 '{name}' 吗？"):
            if self.config_manager.remove_printer(name):
                self.tree.delete(name)
                self.logger.info(f"打印机 '{name}' 已被移除。")
                messagebox.showinfo("成功", f"打印机 '{name}' 已移除。")
            else:
                messagebox.showerror("失败", "移除打印机失败。")

    def open_configure_dialog(self):
        # 获取已选文件的扩展名
        file_extensions = set()
        for file_info in self.files_to_print:
            file_path = file_info["path"]
            ext = os.path.splitext(file_path)[1].lower()
            if ext:  # 确保有扩展名
                file_extensions.add(ext)

        # 如果有选择的文件，只显示相关文件类型
        if file_extensions:
            ConfigurePrinterDialog(self, self.config_manager, list(file_extensions))
        else:
            # 如果没有选择文件，显示所有文件类型
            ConfigurePrinterDialog(self, self.config_manager)

    def select_files(self):
        files = filedialog.askopenfilenames(
            title="选择要打印的文件", filetypes=[("All files", "*.*")]
        )
        if files:
            for file_path in files:
                # 为每个文件创建一个唯一ID和记录
                file_info = {
                    "id": self.next_file_id,
                    "path": file_path,
                    "printed": False,
                }
                self.files_to_print.append(file_info)
                self.next_file_id += 1

            self.update_file_display()
            self.logger.info(f"选择了 {len(files)} 个文件进行打印。")

    def clear_files(self):
        if not self.files_to_print:
            return
        if messagebox.askyesno("确认", "确定要清空待打印文件列表吗？"):
            self.files_to_print.clear()
            self.update_file_display()
            self.logger.info("用户清空了待打印文件列表。")

    def update_file_display(self):
        # 启用文本小部件以修改其内容
        self.file_display_text.config(state=tk.NORMAL)
        # 清除现有内容
        self.file_display_text.delete("1.0", tk.END)

        if not self.files_to_print:
            self.file_display_text.insert(tk.END, "请点击 '选择文件' 添加...")
        else:
            # 插入每个文件路径，带编号和换行
            for i, file_info in enumerate(self.files_to_print):
                file_path = file_info["path"]
                # 检查文件是否已打印
                status = " (已打印)" if file_info["printed"] else ""
                self.file_display_text.insert(
                    tk.END, f"{i + 1}. {file_path}{status}\n\n"
                )

        # 禁用文本小部件，使其对用户只读
        self.file_display_text.config(state=tk.DISABLED)

    def mark_file_as_printed(self, file_id):
        """标记文件为已打印"""
        for file_info in self.files_to_print:
            if file_info["id"] == file_id:
                file_info["printed"] = True
                break
        self.update_file_display()

    def distribute_print_jobs(self):
        if not self.files_to_print:
            messagebox.showwarning("无文件", "请先选择要打印的文件。")
            return

        # 使用分发器分发任务
        success, message = self.distributor.distribute_jobs(
            self.files_to_print, self.mark_file_as_printed
        )

        if success:
            messagebox.showinfo("任务已分配", message)
        else:
            messagebox.showerror("分配失败", message)

    def destroy(self):
        # 关闭分发器的线程池
        self.distributor.shutdown()
        super().destroy()
